/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.querydsl.sql;

import com.google.common.collect.Lists;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.PathMetadata;
import com.querydsl.core.types.PathMetadataFactory;
import com.querydsl.sql.ColumnMetadata;
import com.querydsl.sql.ForeignKey;
import com.querydsl.sql.RelationalPathBase;
import net.apexes.commons.lang.Enume;
import net.apexes.commons.querydsl.Index;
import net.apexes.commons.querydsl.IndexBuilder;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 *
 * @param <E>
 */
public class TablePathBase<E> extends RelationalPathBase<E> {
    
    private static final long serialVersionUID = 1L;

    private final List<Index> indexs = Lists.newArrayList();
    private final Map<String, String> defaultValues = new HashMap<>();
    private final Map<ForeignKey<?>, String> fkPkTables = new HashMap<>();

    public TablePathBase(Class<? extends E> type, String variable, String schema, String table) {
        this(type, PathMetadataFactory.forVariable(variable), schema, table);
    }

    public TablePathBase(Class<? extends E> type, PathMetadata metadata, String schema, String table) {
        super(type, metadata, schema, table);
    }

    protected <P extends Path<?>> P addMetadata(P path, ColumnMetadata metadata, String defaultValue) {
        defaultValues.put(metadata.getName(), defaultValue);
        return super.addMetadata(path, metadata);
    }

    @SuppressWarnings("unchecked")
    protected <F extends Enume<?>> EnumePath<F> createEnume(String property, Class<? super F> type) {
        return add(new EnumePath<F>((Class<F>) type, forProperty(property)));
    }

    protected IndexBuilder index(String name) {
        return new IndexBuilder(this, name, indexs);
    }

    public List<Index> getIndexs() {
        return Collections.unmodifiableList(indexs);
    }

    public String getDefaultValue(String columnName) {
        return defaultValues.get(columnName);
    }

    public boolean hasDefaultValue(Path<?> path) {
        String columnName = getMetadata(path).getName();
        return defaultValues.containsKey(columnName);
    }

    protected <F> ForeignKey<F> createForeignKey(Path<?> local, String pkTable, String pkColumn) {
        ForeignKey<F> foreignKey = super.createForeignKey(local, pkColumn);
        fkPkTables.put(foreignKey, pkTable);
        return foreignKey;
    }

    protected <F> ForeignKey<F> createForeignKey(List<? extends Path<?>> local, String pkTable, List<String> pkColumns) {
        ForeignKey<F> foreignKey = super.createForeignKey(local, pkColumns);
        fkPkTables.put(foreignKey, pkTable);
        return foreignKey;
    }

    public <F> String getPkTableName(ForeignKey<F> foreignKey) {
        return fkPkTables.get(foreignKey);
    }

}
